An operating system (OS) is a set of programs that manage computer hardware resources and provide common services for application software. In many cases, developers of operating systems will organize the various management and service functions that the operating system provides into a set of components. These components may cover aspects of the operating system such as networking, security, and the user interface.
One component, referred to as the kernel, is generally considered the main component of the operating system and acts as a bridge between the applications and the data processing performed at the hardware level. The kernel's basic functions typically include process management, memory management, device management, and system calls. The kernel may also be compartmentalized into several subsystems, each of which controlling a different functionality. For example, one subsystem may implement a virtual file system and another subsystem may implement the kernel's scheduler.
A conventional computer operating system typically segregates virtual memory into kernel space and user space. Kernel space is reserved for running the kernel and user space is the memory area where all user mode applications work.
In order to protect the operation of the kernel, many central processing unit (CPU) architectures implement modes which can place restrictions on the type and scope of operations performed by certain processes being run by the CPU. Typically, a CPU will support at least two modes. Kernel mode, also known as supervisor mode, has unrestricted access to the computer's resources. For example, in kernel mode the CPU may perform any operation allowed by its architecture, execute any instruction, initiate any I/O operation, and access any area of memory. By contrast, user mode is restricted and certain instructions are not permitted. For example, an application running in user mode may be restricted from accessing memory locations in kernel space.
In some implementations, an application running in user mode gains access to resources reserved to the kernel by making a system call which requests a service provided by the kernel. This system call causes the CPU to switch from user mode to kernel mode and invokes the kernel which then performs the requested service on behalf of the application. Typically, system calls are implemented by a software interrupt that transfers control to the kernel. As a result, an application making a system call sets a register with an identifier unique to the particular system call being made and triggers the interrupt. Once control is transferred to the kernel, the kernel looks up the identifier in a table, known as a system call table, to locate the memory address of the code that that will be executed to perform the system call's service. In addition, in order to pass parameters for the system call, the application sets other registers with memory addresses specifying the location of the parameters, which will often times reference the application's own call stack.
Due to the power that kernel mode possesses, great care is taken in selecting the code allowed to run within the kernel. Malicious code which finds its way into the kernel can often times be difficult to detect and can cause undesirable results ranging from a system crash to an attacker taking control of the system. Typically, users and administrators only run code within the kernel that comes from a trusted source, such as the developer or owner of the particular subsystem that the code is intended to implement, extend, or modify.
Balanced against the danger of introducing code into the kernel is the desire to add functionality to the kernel which may not have existed at the time the kernel was originally loaded into the system.
In some cases, an application may require metrics regarding a subsystem's performance of the application's tasks. User space tools can be used to collect a fairly wide range of application level metrics using existing OS provided library and system calls. However, customized application specific views into operating system information are generally not available. For example, conventional OS IO metric collection APIs do not offer access to fine grained characterizations of the IO access patterns of a specific application or application group of processes nor the ability to direct the collection of the metrics.
Furthermore, in other cases, an application may require content management information from the subsystem. For example, an application may be interested in monitoring changes made by itself or other applications to a particular set of files. However, customized application specific reports into the modification history of files are generally not available from a conventional OS.
More often than not, the applications which require the customized functionality do not come from a trusted source such as those previously mentioned. As such, applications are typically not allowed to load code into the kernel to create the extended functionality. Furthermore, even if the applications were trusted, without support from the kernel subsystem no interface would exist to allow the application to communicate to the subsystem when and how the new functionality should be applied. Therefore, support of application specific policies for conventional operating systems remains an ongoing problem.
The approaches described in this section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.